package top.wyloop.intoeins.module.iam.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import top.wyloop.intoeins.module.iam.model.consts.AuthorityConst;
import top.wyloop.intoeins.module.iam.model.entity.Permission;
import top.wyloop.intoeins.module.iam.model.form.PermissionCondition;
import top.wyloop.intoeins.module.iam.model.form.PermissionForm;
import top.wyloop.intoeins.module.iam.service.PermissionService;
import top.wyloop.intoeins.response.Response;

import java.util.List;

/**
 * @author Wyatt6
 * @date 2025/2/8
 */
@Slf4j
@RestController
@RequestMapping("/api/iam/permission")
public class PermissionController {
    @Autowired
    private PermissionService permissionService;

    /**
     * 新增权限
     *
     * @param input 新权限信息
     * @return permission 新权限对象
     */
    @SaCheckLogin
    @SaCheckPermission(AuthorityConst.PERMISSION_ADD)
    @PostMapping("/add")
    @Transactional(isolation = Isolation.SERIALIZABLE)
    public Response addPermission(@RequestBody PermissionForm input) {
        log.info("[[新增权限]]");
        Assert.notNull(input, "新权限信息为空");
        Assert.hasText(input.getIdentifier(), "权限标识符为空");
        log.info("请求参数: {}", input);

        Permission permission = permissionService.createPermission(input.convert());
        return new Response().success().addData("permission", permission);
    }

    /**
     * 删除权限
     *
     * @param permissionId 要删除的权限ID
     */
    @SaCheckLogin
    @SaCheckPermission(AuthorityConst.PERMISSION_DELETE)
    @GetMapping("/delete")
    @Transactional(isolation = Isolation.SERIALIZABLE)
    public Response deletePermission(@RequestParam("permissionId") Long permissionId) {
        log.info("[[删除权限]]");
        Assert.notNull(permissionId, "权限ID为空");
        log.info("请求参数: permissionId=[{}]", permissionId);

        permissionService.deletePermission(permissionId);
        return new Response().success();
    }

    /**
     * 修改权限
     *
     * @param input 要修改的权限数据
     * @return permission 新权限对象
     */
    @SaCheckLogin
    @SaCheckPermission(AuthorityConst.PERMISSION_EDIT)
    @PostMapping("/edit")
    public Response editPermission(@RequestBody PermissionForm input) {
        log.info("[[修改权限]]");
        Assert.notNull(input, "权限信息为空");
        Assert.notNull(input.getId(), "权限ID为空");
        log.info("请求参数: {}", input);

        Permission permission = permissionService.updatePermission(input.convert());
        return new Response().success().addData("permission", permission);
    }

    /**
     * 获取全量权限数据
     *
     * @return 全量权限数据
     */
    @SaCheckLogin
    @SaCheckPermission(AuthorityConst.ROLE_QUERY)
    @GetMapping("/getPermissions")
    public Response getPermissions() {
        log.info("[[获取全量权限数据]]");
        List<Permission> permissions = permissionService.listPermissions();
        return new Response().success().addData("permissions", permissions);
    }

    /**
     * 查询某角色所具有的权限ID列表
     *
     * @param roleId 角色ID
     * @return 该角色所具有的权限ID列表
     */
    @SaCheckLogin
    @SaCheckPermission(AuthorityConst.PERMISSION_QUERY)
    @GetMapping("/getPermissionIdsOfRole")
    public Response getPermissionIdsOfRole(@RequestParam("roleId") Long roleId) {
        log.info("[[查询某角色所具有的权限ID列表]]");
        Assert.notNull(roleId, "角色ID为空");

        List<Long> permissionIds = permissionService.getPermissionIdsOfRole(roleId);
        return new Response().success().addData("permissionIds", permissionIds);
    }

    /**
     * （条件）查询权限分页
     * 查询条件为空时查询全量数据
     *
     * @param pageNum   页码
     * @param pageSize  页大小
     * @param condition 查询条件
     * @return {pageNum 页码, pageSize 页大小, totalPages 页码总数, totalElements 总条数, permissions 权限分页数据}
     */
    @SaCheckLogin
    @SaCheckPermission(AuthorityConst.PERMISSION_QUERY)
    @PostMapping("/getPermissionsByPage")
    public Response getPermissionsByPage(@RequestParam("pageNum") int pageNum,
                                         @RequestParam("pageSize") int pageSize,
                                         @RequestBody(required = false) PermissionCondition condition) {
        log.info("[[（条件）查询权限分页]]");
        log.info("请求参数：pageNum=[{}], pageSize=[{}], condition=[{}]", pageNum, pageSize, condition);

        Page<Permission> permissions = permissionService.getPermissionsByPageConditionally(
                pageNum,
                pageSize,
                (condition == null || condition.getModule() == null) ? null : condition.getModule(),
                (condition == null || condition.getIdentifier() == null) ? null : condition.getIdentifier(),
                (condition == null || condition.getName() == null) ? null : condition.getName(),
                (condition == null || condition.getActivated() == null) ? null : condition.getActivated(),
                (condition == null || condition.getStTime() == null) ? null : condition.getStTime(),
                (condition == null || condition.getEdTime() == null) ? null : condition.getEdTime());

        return new Response().success()
                .addData("pageNum", permissions.getPageable().getPageNumber())
                .addData("pageSize", permissions.getPageable().getPageSize())
                .addData("totalPages", permissions.getTotalPages())
                .addData("totalElements", permissions.getTotalElements())
                .addData("permissions", permissions.getContent());
    }

    /**
     * 查询权限的排名（从1开始）
     *
     * @param permissionId 权限ID
     */
    @SaCheckLogin
    @SaCheckPermission(AuthorityConst.PERMISSION_QUERY)
    @GetMapping("/getRowNumStartFrom1")
    public Response getRowNumStartFrom1(@RequestParam("permissionId") Long permissionId) {
        log.info("[[查询权限的排名（从1开始）]]");
        Assert.notNull(permissionId, "权限ID为空");
        return new Response().success().addData("rowNum", permissionService.getRowNum(permissionId));
    }
}
